﻿using System;
using System.Collections.Generic;
using System.Linq;
using Castle.MonoRail.Framework;
using Castle.MonoRail.Framework.Helpers;
using Castle.MonoRail.ViewComponents;
using StateTheater.Models;
using Castle.Core;

namespace StateTheater.Component
{
	using Event = Pair<DateTime, int>;
	using EventList = List<Pair<DateTime, int>>;
	using EventsMap = Dictionary<DateTime, List<Pair<DateTime, int>>>;

	public class CalendarComponent : ViewComponentEx
	{
		[ViewComponentParam]
		public EventList Events { get; set; }

		public override void Render()
		{
			base.Render();

			DateTime first = Events.First().First;

			EventsMap eventsMap = new EventsMap();
			foreach (Event evnt in Events)
			{
				DateTime dy = evnt.First.Date;
				if (!eventsMap.ContainsKey(dy))
					eventsMap.Add(dy, new EventList());

				eventsMap[dy].Add(evnt);
//				RenderTextFormat("{0} - {1} <br/>", dy, ti);
			}
			DateTime last = Events.Last().First;
			DateTime startmonth = new DateTime(first.Year, first.Month, 1);
			for (DateTime mon = startmonth; mon <= last; mon = mon.AddMonths(1))
			{
				RenderCalendar(mon, eventsMap);
				RenderText("<br/>");
			}
			CancelView();

		}
		private void RenderCalendar(DateTime month, EventsMap perfs)
		{
			DateTime startcalendar = month.AddDays(-(int)month.DayOfWeek);
			DateTime endmonth = month.AddMonths(1).AddDays(-1);
			DateTime endcalendar = endmonth.AddDays(6 - (int)endmonth.DayOfWeek);
			int cnt = 0;
			RenderText(@"<table class=""monthgrid"">");
			RenderTextFormat(@"<tr><td class=""monthname"" colspan=""7"">{0:MMMM yyyy}</td></tr>", month);

			RenderText("<tr>");
			foreach(string dow in Enum.GetNames(typeof(DayOfWeek)))
				RenderTextFormat(@"<td class=""downame"">{0}</td>", dow);
			RenderText("</tr>");


			for (DateTime dy = startcalendar; dy <= endcalendar; dy = dy.AddDays(1))
			{
				string cssClass = "weekday";

				if (dy.DayOfWeek == DayOfWeek.Sunday || dy.DayOfWeek == DayOfWeek.Saturday)
					cssClass = "weekend";

				if ((cnt % 7) == 0)
					RenderText("<tr>");

				if (dy >= month && dy <= endmonth)
				{
					RenderTextFormat(@"<td class=""day {1}""><span class=""daynumber"">{0}</span><br/>", dy.Day, cssClass);
					int br = 3;
					if (perfs.ContainsKey(dy))
					{
						foreach (Event sp in perfs[dy])
						{
							RenderText(@"<span class=""perftime"">");
							RenderText(LinkTo(" {0:h:mm tt}".With(sp.First), "Show", "vCard", sp.Second));
							RenderText("</span><br/> ");
							--br;
						}
					}
					while (br > 0)
					{
						RenderText("<br/>");
						--br;
					}
					RenderText("</td>");
				}
				else
					RenderText(@"<td class=""day outsidemonth""><br/><br/><br/></td>");

				if ((cnt % 7) == 7)
					RenderText("</tr>");
				cnt++;
			}
			RenderText("</table>");

		}

		private string LinkTo(string innerContent, string controller, string action, int id)
		{
			string siteRoot = PropertyBag["siteRoot"] as string;

			return @"<a href=""{4}/{0}/{1}.rails?id={2}"">{3}</a>".With(controller, action, id, innerContent, siteRoot);
		}
	}
}
